home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2003 March / DPPCPRO0303.ISO / Components / Microsoft ASP / _SETUP.1 / MSDBNav.inc < prev    next >
Encoding:
Text File  |  1998-11-20  |  19.1 KB  |  526 lines

  1. <!--#INCLUDE FILE="MSGlobal.inc"-->
  2. <SCRIPT RUNAT=SERVER LANGUAGE=JSCRIPT>
  3. ////////////////////////////////////////////////////////////////////
  4. //                                                                //
  5. //   Fusion ASP Components                                          //
  6. //   Custom JScript Object: MSDBNav                                  // 
  7. //                                                                //
  8. ////////////////////////////////////////////////////////////////////
  9. /*
  10. Object:       MSDBNav
  11.  
  12. Version:      1.0  10/02/97
  13.  
  14. Written By:   Application Methods, Inc.
  15.               6300 Southcenter Blvd.
  16.               Seattle, WA 98188
  17.               (206) 244-2400
  18.               http://www.appmethods.com
  19.  
  20. Description:   This object definition describes properties and methods for a 
  21.    dynamically constructed set of navigator buttons.  From this object definition,
  22.    the buttons use an existing query comonent on the page to construct links that
  23.    allow the user to navigate to a previous and next record. For the buttons to
  24.    work, the user must define at least one unique column in the query as a key field,
  25.    otherwise, the navigator buttons will not appear. They are also designed so that
  26.    the user will not see a previous button if the user is at the start of the 
  27.    recordset, and likewise the next button will not appear at the end of the recordset.
  28.    If the query is defined so that only one record is returned, neither the next or previous
  29.    buttons will appear.
  30.    
  31.  
  32. Note:   Generation of a number of hidden fields is necessary to pass information
  33.    on to other components.  All hidden fields created by this object are prefixed
  34.    with 'amASPHidden_' or 'amASPComponent_'.  Devlopers should never create
  35.    any form element with these prefixes or unexpected results will occur.
  36.  
  37. Properties:
  38.    name - Name of navigator component
  39.    queryComponent - Name of query component
  40.    previousImage - Path to previous image
  41.    nextImage - Path to next image
  42.    returnImage - Path to return image
  43.    keyFieldCount - Number of key fields
  44.    keyFieldNames - Key field names
  45.    keyFieldTypes - Key field types
  46.    pageName - Name of page this component resides on
  47.    returnPageName - Name of page to jump to when return button is clicked
  48.    numRecords - Number of records to advance
  49.    detailPage - Whether this is a detail page (single record view)                   
  50.  
  51. Methods:
  52.    render - renders all visual elements of component
  53.    createRequestStrings - builds request string
  54.    generateString - builds Navigation advancement string
  55.    emitProperties - emits all object's properties
  56.    getNumRecords - gets number of records to advance
  57.    setDetailArray - gets the values of the keyfields
  58.    createBaseCursor - creates cursor passed to query
  59.    keyFieldMatch - determines existance of fields in query
  60.    findMatch - locates selected record in recordset
  61.  
  62. Usage:  The following example shows a row in a record set being displayed by 4 dynafields
  63.    containing a value from the table "lookup." The usage will script will not work properly unless 
  64.    the code for the DataBase Connection and Query Components has been installed is part of your build file.
  65.  
  66. <HTML>
  67. <HEAD>
  68.  
  69. <!SCRIPT RUNAT=SERVER LANGUAGE=JSCRIPT>
  70.  
  71.    // Create and connect the database object
  72.    MSDBConnection1 = new MSDBConnection("test", "ODBC","MS Access", "Northwind","admin","",false);
  73.    MSDBConnection1.connect();
  74.  
  75.    // Create the query object
  76.    MSDBQuery1 = new MSDBQuery("MSDBQuery1", "MSDBConnection1", false, "*", "Customers", "customerID > 7", "lastname");
  77.  
  78.    // Create the dynafield object
  79.    MSDBDynaField1 = new MSDBDynaField( "MSDBDynaField1",
  80.                             "true",   
  81.                             "MSDBQuery1",
  82.                             "",
  83.                             "ShipCity",
  84.                             "string",
  85.                             "false",
  86.                             10,
  87.                             10,
  88.                             1,
  89.                             "Arial",
  90.                             "+0",
  91.                             "black",
  92.                             "false",
  93.                             "false",
  94.                             "false");
  95.  
  96.    var keyFields = new Array(1);
  97.    keyFields [1] = "OrderID";
  98.  
  99.    var keyFieldTypes = new Array(1);
  100.    keyFieldTypes [1] = "number";
  101.                                                     
  102.    MSDBNav1 = new MSDBNav("MSDBNav1",
  103.                           "MSDBQuery1",
  104.                           "prev.jpg",                                                                              
  105.                           "next.jpg",
  106.                           "return.jpg",
  107.                           1,
  108.                           keyFields,
  109.                           keyFieldTypes,
  110.                           "test.html",
  111.                           "Adhoc.htm",
  112.                           1,
  113.                           "true");
  114.                                
  115. <!/SCRIPT>
  116.  
  117. <META NAME="Generator" CONTENT="NetObjects Fusion 2.0 for Windows">
  118.  
  119. </HEAD>
  120. <body>
  121.    
  122.    write("<FORM METHOD=POST>");   
  123. <%
  124.    MSDBConnection1.render()
  125.    MSDBDynaField1.render()
  126.    MSDBNav1.render()
  127. %>
  128.    write("</FORM>");
  129.    
  130. </BODY>
  131. </HTML>
  132.  
  133. <META NAME="Generator" CONTENT="NetObjects Fusion 2.0.1 for Windows">
  134.  
  135. <BODY>
  136. <SERVER>
  137. write("<FORM METHOD=POST><BR><BR><BR><BR><CENTER>");
  138. MSDBDynaField1.render();
  139. MSDBDynaField2.render();
  140. MSDBDynaField3.render();
  141. MSDBDynaField4.render();
  142. write("<BR><BR>");
  143. MSDBNav1.render();
  144. write("</FORM></CENTER>");
  145.  
  146.  
  147. </SERVER>
  148.  
  149. </BODY>
  150. </HTML>
  151.  
  152. =====================================================================*/
  153.  
  154. //
  155. // MSDBNav object constructor
  156. //
  157. function MSDBNav(name,
  158.                  queryComponent,
  159.                  previousImage,
  160.                  nextImage,
  161.                  returnImage,
  162.                  keyFieldCount,
  163.                  keyFieldNames,
  164.                  keyFieldTypes,
  165.                  pageName,
  166.                  returnPageName,
  167.                  numRecords,
  168.                  detailPage)                     
  169.    // Set Properties
  170.    this.name                = name;
  171.    this.queryComponent  = queryComponent;
  172.    this.previousImage   = previousImage;
  173.    this.returnImage     = returnImage;
  174.    this.nextImage       = nextImage;
  175.    this.pageName        = pageName;
  176.    this.returnPageName  = returnPageName;
  177.    this.keyFieldCount   = (keyFieldCount+"" != "null") ? parseInt(keyFieldCount) : 0;
  178.    this.numRecords        = numRecords;
  179.    this.move                = "next";
  180.    this.detailPage        = detailPage;
  181.    this.validRecord        = false;
  182.  
  183.    if (keyFieldNames != null) 
  184.       this.keyFieldNames = keyFieldNames;
  185.    else {
  186.       var temp1 = new Array();
  187.       for (var i = 0; i < keyFieldCount; i++) 
  188.           temp1[i] = "";
  189.       
  190.       this.keyFieldNames = temp1;
  191.    }
  192.  
  193.    if (keyFieldTypes != null) 
  194.       this.keyFieldTypes = keyFieldTypes;
  195.    else {
  196.       var temp1 = new Array();
  197.       for (var i = 0; i < keyFieldCount; i++) 
  198.           temp1[i] = "";
  199.       
  200.       this.keyFieldTypes = temp1;
  201.    }
  202.  
  203.    this.detailArray                   = new Array();
  204.    this.nextRequestString           = null;
  205.    this.lastRequestString           = null;
  206.    this.returnPageURLString      = null;
  207.  
  208.    // Set Methods   
  209.    this.render                 = naRender;
  210.    this.createRequestStrings   = naCreateRequestStrings;
  211.    this.generateString            = naGenerateString;
  212.    this.emitProperties         = naEmitProperties;
  213.    this.getNumRecords              = naNumRecords;
  214.    this.setDetailArray         = naSetDetailArray;
  215.    this.createBaseCursor       = naCreateBaseCursor;
  216.    this.keyFieldMatch          = naKeyFieldMatch;
  217.    this.findMatch              = naFindMatch;
  218.    
  219.    // Increment global cursor usage counter since this component will try to use the cursor
  220.    incCursorCallCount();
  221.  
  222. }    // END MSDBNav Constructor
  223.  
  224.  
  225. //
  226. // Method - naEmitProperties()
  227. // Emits all the object's properties.  Used as a debuging tool to verify correct
  228. // manipulation of the object.
  229. //
  230. function naEmitProperties ()
  231. {
  232.       write("\n<BR><B>MSDBNavigator Properties:</B>");
  233.       write("\n<BR>name = " + this.name);
  234.       write("\n<BR>queryComponent = " + this.queryComponent);
  235.       write("\n<BR>previousImage = " + this.previousImage);
  236.       write("\n<BR>nextImage = " + this.nextImage);
  237.       write("\n<BR>returnImage = " + this.returnImage);
  238.       write("\n<BR>pageName = " + this.pageName);
  239.       write("\n<BR>returnPageName = " + this.returnPageName);
  240.       write("\n<BR>numRecords = " + this.numRecords);
  241.       write("\n<BR>detailPage = " + this.detailPage);
  242.  
  243.       var i;
  244.       for (i = 0; i < this.keyFieldCount; i++) {
  245.         write("\n<BR>keyFieldNames" + i + " = " + this.keyFieldNames[i]);
  246.         write("\n<BR>keyFieldDataTypes" + i + " = " + this.keyFieldTypes[i]);
  247.       }     
  248.       write("<BR>");
  249. }    // END naEmitProperties
  250.  
  251.  
  252. //
  253. // Method to output the appropriate HTML to render the object's 
  254. // HTML elements.
  255. //
  256. function naRender() {   
  257.    // Get the value of the hidden field amlivewireHidden_URLStr.
  258.    // This request object property contains the URL encoded string
  259.    // that is to be appended to the returnPage URL so that the query
  260.    // component on that page can filter on the appropriate field and
  261.    // value. The Prev and Next button URLs need to carry this along 
  262.    // so that the property remains in the request object.
  263.    returnPageURLString = eval(this.queryComponent + ".getURLStr()");
  264.    
  265.    addClientStr = "";
  266.    
  267.    // Create request strings for next and previous buttons
  268.    this.createRequestStrings();   
  269.  
  270.    // PREVIOUS Button
  271.    // If there is a valid value for the link, show the button   
  272.    if (this.lastRequestString != null) {
  273.       addClientStr = this.pageName + "?" + this.lastRequestString;
  274.       if ((returnPageURLString != null) && 
  275.           (returnPageURLString != ""))
  276.          addClientStr += "&amaspHidden_URLStr=" + escape(returnPageURLString);
  277.  
  278.       write("<A HREF=" + addClientStr + ">");
  279.       write("<IMG SRC=\"" + this.previousImage + "\" BORDER=0></A>");
  280.    }   
  281.  
  282.    // RETURN (UP) Button
  283.    if (this.returnImage != null)   {
  284.       addClientStr = this.returnPageName;
  285.       if ((returnPageURLString != null) && 
  286.           (returnPageURLString != ""))
  287.          addClientStr += "?" + returnPageURLString;
  288.  
  289.       write("<A HREF=" + addClientStr + ">");
  290.       write("<IMG SRC=\"" + this.returnImage + "\" BORDER=0></A>");
  291.    }
  292.  
  293.       // NEXT Button
  294.    // If there is a valid value for the link, show the button   
  295.    if (this.nextRequestString != null) {
  296.       addClientStr = this.pageName + "?" + this.nextRequestString;
  297.       if ((returnPageURLString != null) && 
  298.           (returnPageURLString != ""))
  299.          addClientStr += "&amaspHidden_URLStr=" + escape(returnPageURLString);
  300.  
  301.       write("<A HREF=" + addClientStr + ">");
  302.       write("<IMG SRC=\"" + this.nextImage + "\" BORDER=0></A>");
  303.    }
  304.       
  305.    // Decrement global cursor usage counter since this component has tried to use the cursor
  306.    // If the counter has reached zero after doing so, then this is the last cursor using
  307.    // component on the page, so call the DBQuery object's "cursorClose()" method to close
  308.    // the cursor if it's still open.
  309.      decCursorCallCount(this.queryComponent);
  310.  
  311. }    // END naRender
  312.  
  313. //
  314. // Method that returns an array that contains the VALUES of the 
  315. // Key Fields in the keyFieldNames array.
  316. //
  317. function naSetDetailArray() {
  318.  
  319.    // construct a cursor based on the sql for the Query Component
  320.    getDetailCursor = eval(this.queryComponent + ".getCurrentCursor()");
  321.  
  322.    if (getDetailCursor != null && !eval(this.queryComponent + ".isCursorEnd()")) {  
  323.        // Initialize the cursor then create array
  324.        if (!eval(this.queryComponent + ".isCursorInitialized")) 
  325.           eval(this.queryComponent + ".initializeCursor()");      
  326.  
  327.        var x = 0;
  328.  
  329.        // Fill the detail Array in the same order that the User Created 
  330.        // the key fields.         
  331.        for (x = 0; x < this.keyFieldCount; x++) {
  332.            if (this.keyFieldTypes[x].toUpperCase() == "DATE")         
  333.               this.detailArray[x] = formatDate(getDetailCursor.Fields(this.keyFieldNames[x]));
  334.           else
  335.               this.detailArray[x] = getDetailCursor.Fields(this.keyFieldNames[x]);
  336.        } // end For Loop  
  337.    }
  338.    else {
  339.       write("\n<BR>No matching record was found.\n<BR>\n<BR>");            
  340.    }  
  341.  
  342.    return this.detailArray;
  343.    
  344. }    // END naSetDetailArray
  345.    
  346. //
  347. // Method that returns boolean result of matching values in the detailArray
  348. // with the values of the key fields from the baseCursor's current 
  349. // record.
  350. //
  351. function naKeyFieldMatch() {   
  352.    match = true;
  353.    // Loop through the keyfields
  354.    for (x = 0; x < this.keyFieldCount; x++) {
  355.       searchCursor = this.baseCursor;
  356.  
  357.       // compare the key field value to the match criteria
  358.       if (this.keyFieldTypes[x].toUpperCase() == "DATE")
  359.           var keyFieldValue = formatDate(searchCursor.Fields(this.keyFieldNames[x]));
  360.       else
  361.           var keyFieldValue = searchCursor.Fields(this.keyFieldNames[x]);
  362.  
  363.       if (keyFieldValue + "" != this.detailArray[x] + "") {
  364.          match = false;
  365.          break;
  366.       } // end if       
  367.    } // end for
  368.    return match;
  369.    
  370. }    // END naKeyFieldMatch
  371.  
  372.  
  373. //
  374. //   Method loops through the baseCursor to find the matching record.
  375. //
  376. function naFindMatch() {
  377.         var count = 0;
  378.       found = false;
  379.       while (!found) {
  380.          // call the match function            
  381.          if (this.keyFieldMatch())
  382.          {               
  383.             found = true;
  384.             // leave loop, a match was found   
  385.             break;   
  386.          }   // end if keyFieldMatch
  387.          ret = (eval(this.queryComponent + ".moveNext(1)"));
  388.          count = count + ret;
  389.                
  390.          if (eval(this.queryComponent + ".isCursorEnd()")) {
  391.             // Cannot Advance Cursor and no match is found -- move to beginning of recordset
  392.             ret = (eval(this.queryComponent + ".movePrevious(" + count + ")"));    
  393.             break;               
  394.          }
  395.       } // end while (!found)                                                    
  396.       
  397.       this.validRecord = found;
  398.       
  399. }    // END naFindMatch
  400.  
  401.  
  402. //
  403. // Method that creates the baseCursor based on the query component's
  404. // SQL properties. (This creates a cursor based on the initial query, 
  405. // not any fields that got passed in.)
  406. //
  407. function naCreateBaseCursor() {
  408.     // Create a base cursor only if on a detail page and not already navigating
  409.     if ((!(eval(this.queryComponent + ".isNavigating()"))) && this.detailPage) {
  410.        // Create the array of values to match on
  411.        this.setDetailArray(); 
  412.  
  413.        // Use the query component's SELECT and FROM clauses as is
  414.        baseSQL = "select " + eval(this.queryComponent + ".select") + " ";
  415.        baseSQL += "from " + eval(this.queryComponent + ".from") + " ";
  416.          
  417.        // Use the query component's WHERE clause if available
  418.        if ((eval(this.queryComponent + ".where") != null) && (eval(this.queryComponent + ".where") != "")) {
  419.           baseSQL += "where (" + eval(this.queryComponent + ".where") + ") ";
  420.        }
  421.  
  422.        // Use the query component's ORDER BY clause is avaialable
  423.        if ((eval(this.queryComponent + ".orderBy") != null) && (eval(this.queryComponent + ".orderBy") != ""))
  424.             baseSQL += "order by " + eval(this.queryComponent + ".orderBy");
  425.  
  426.         // Create the base cursor based using query component's openCursor() method which will also overwrite
  427.         // the query component's old cursor
  428.        this.baseCursor = eval(this.queryComponent + ".openCursor(baseSQL)"); // bug fix, 11/26/97
  429.  
  430.        
  431.        // Locate the initial record
  432.        this.findMatch();   
  433.    }  // END if ((!(eval(this.queryComponent + ".isNavigating"))) && this.detailPage)
  434.    else {
  435.        this.baseCursor = eval(this.queryComponent + ".getCurrentCursor()");
  436.        eval(this.queryComponent + ".initializeCursor()");
  437.        this.validRecord = true;
  438.    }
  439.        
  440. }    // END naCreateBaseCursor();
  441.  
  442.  
  443. //
  444. // Method loops through the query component's cursor to determine which, if either, 
  445. // of the navigation buttons to display.
  446. //
  447. function naCreateRequestStrings() {   
  448.       this.nextRequestString  = null;
  449.       this.lastRequestString  = null;
  450.       
  451.       // Create a base cursor when on a detail page and not navigating
  452.       this.createBaseCursor();
  453.       
  454.       // Only show next and/or previous buttons if we're at a valid record in the recordset
  455.       if (this.validRecord) {
  456.           // Advance the recordset this.numRecords + 1 times to check for end of recordset
  457.           var i = 0;
  458.           var ret = 0;
  459.           var count = 0;
  460.       
  461.           ret = (eval(this.queryComponent + ".moveNext(" + (1 + this.numRecords) + ")"));
  462.           
  463.            // If we aren't at the end of the recordset then show next button
  464.           if (parseInt(ret, 10) == parseInt((this.numRecords + 1), 10)) {
  465.               if (parseInt(ret, 10) > this.numRecords)          
  466.                  this.nextRequestString = this.generateString("next", this.numRecords);
  467.               else
  468.                   this.nextRequestString = this.generateString("next", ret);
  469.            }
  470.           else
  471.               this.nextRequestString = null;
  472.          
  473.              // Rewind the recordset to initial position
  474.           ret = (eval(this.queryComponent + ".movePrevious(" + ret + ")"));
  475.       
  476.              // Move to the record two before the initial record to check for beginning of recordset
  477.              ret = (eval(this.queryComponent + ".movePrevious(2)"));
  478.       
  479.              // If we aren't at the beginning of the recordset then show previous button
  480.              if (parseInt(ret, 10) == 2)            
  481.                  this.lastRequestString = this.generateString("previous", this.numRecords);
  482.           else
  483.               this.lastRequestString = null;
  484.           
  485.              // Move recordset to initial position
  486.              ret = (eval(this.queryComponent + ".moveNext(" + ret + ")"));
  487.         } // end if (this.validRecord)
  488.                                      
  489. }    // END naCreateRequestStrings
  490.  
  491.  
  492. //
  493. // Method that create a request string based on the direction being moved and the number of records
  494. // by which to navigate.
  495. //
  496. function naGenerateString(navDir, navCount) {   
  497.    var pre = "amaspHidden_";  // Required so that DBQuery will ignore the property 
  498.  
  499.    var requestString = "";
  500.    
  501.    // Add the direction to move to the request string
  502.    requestString = pre + "NavDir=" + navDir;
  503.  
  504.    // Calculate the ordinal position of the recordset for the next page
  505.    if (navDir.toUpperCase() == "NEXT")
  506.        requestString += "&" + pre + "NavPosition=" + (parseInt(eval(this.queryComponent + ".cursorPosition"), 10) + parseInt(navCount, 10));
  507.    else
  508.        requestString += "&" + pre + "NavPosition=" + (parseInt(eval(this.queryComponent + ".cursorPosition"), 10) - parseInt(navCount, 10));
  509.    
  510.    // Add the number of records to navigate to the request string
  511.    requestString += "&" + pre + "NavCount=" + navCount;
  512.    
  513.    // Check for "listActive" flag - if true, append to request string
  514.    // This is necessary to make "Use Previous Query" (see DBQuery) work in conjunction with navigation
  515.    if ( eval(this.queryComponent + ".listActive") )
  516.       requestString += pre + "listActive=true";
  517.  
  518.    return requestString;   
  519. }    // END naGenerateString
  520.  
  521. function naNumRecords() {
  522.     return this.numRecords;
  523. } // END naNumRecords
  524.  
  525. </SCRIPT>